package com.android.corestat.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.util.Log;

/**
 * 类说明：
 * 
 * @author Baker.li
 * @date 2014年4月22日
 * @version 1.0
 */

public final class CSLog {
	public static boolean ENABLE = false;
	public static boolean DETAIL = false;

	/* Protect from instantiations */
	private CSLog() {
	}

	private static String[] getDetail(int level) {
		// Throwable instance must be created before any methods
		StackTraceElement[] se = new Throwable().getStackTrace();
		String cls = se[level].getClassName();
		String method = se[level].getMethodName();
		String line = String.valueOf(se[level].getLineNumber());
		return new String[] { cls, method, line };
	}

	public static void e(String tag, String msg) {
		if (!ENABLE)
			return;
		if (DETAIL) {
			String[] d = getDetail(2);
			msg = String.format("[%s:%s,%s]%s", d[0], d[1], d[2], msg);
		}
		if (sFileLog) {
			writeFile("E", tag, msg);
		}
		Log.e(tag, msg);
	}

	public static void i(String tag, String msg) {
		if (!ENABLE)
			return;
		if (DETAIL) {
			String[] d = getDetail(2);
			msg = String.format("[%s:%s,%s]%s", d[0], d[1], d[2], msg);
		}
		if (sFileLog) {
			writeFile("I", tag, msg);
		}
		Log.i(tag, msg);
	}

	public static void d(String tag, String msg) {
		if (!ENABLE)
			return;
		if (DETAIL) {
			String[] d = getDetail(2);
			msg = String.format("[%s:%s,%s]%s", d[0], d[1], d[2], msg);
		}
		if (sFileLog) {
			writeFile("D", tag, msg);
		}
		Log.d(tag, msg);
	}

	public static void v(String tag, String msg) {
		if (!ENABLE)
			return;
		if (DETAIL) {
			String[] d = getDetail(2);
			msg = String.format("[%s:%s,%s]%s", d[0], d[1], d[2], msg);
		}
		if (sFileLog) {
			writeFile("V", tag, msg);
		}
		Log.v(tag, msg);
	}

	public static void w(String tag, String msg) {
		if (!ENABLE)
			return;
		if (DETAIL) {
			String[] d = getDetail(2);
			msg = String.format("[%s:%s,%s]%s", d[0], d[1], d[2], msg);
		}
		if (sFileLog) {
			writeFile("W", tag, msg);
		}
		Log.w(tag, msg);
	}

	public static void setFileLogEnable(Context context, boolean enable) {
		if (!enable) {
			sFileLog = false;
			return;
		}
		if (context == null) {
			Log.d("LogUtil", "context is null");
			return;
		}
		sFileLog = true;
		sFileName = context.getPackageName() + "-cs.log";
		return;
	}

	private static boolean sFileLog = false;
	private static String sFileName;
	private static Handler sHandler;
	private static SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

	private static void writeFile(final String level, final String tag, final String log) {
		if (sHandler == null) {
			HandlerThread ht = new HandlerThread("log");
			ht.start();
			sHandler = new Handler(ht.getLooper());
		}
		sHandler.post(new Runnable() {
			@Override
			public void run() {
				File file = new File(Environment.getExternalStorageDirectory(), sFileName);
				if (file.length() > 1024 * 1024 * 5) {// 5M
					Log.d("Log", "log file too large");
					return;
				}
				try {
					FileWriter writer = new FileWriter(file, true);
					String content = String.format("%s %-4s%-20s%s\r\n",
							sFormatter.format(new Date()), level, tag, log);
					writer.write(content);
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
	}

	public static String timeSinceBoot() {
		long ms = SystemClock.elapsedRealtime();
		int ss = 1000;
		int mi = ss * 60;
		int hh = mi * 60;
		int dd = hh * 24;

		long day = ms / dd;
		long hour = (ms - day * dd) / hh;
		long minute = (ms - day * dd - hour * hh) / mi;
		long second = (ms - day * dd - hour * hh - minute * mi) / ss;
		long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

		String strDay = day < 10 ? "0" + day : "" + day;
		String strHour = hour < 10 ? "0" + hour : "" + hour;
		String strMinute = minute < 10 ? "0" + minute : "" + minute;
		String strSecond = second < 10 ? "0" + second : "" + second;
		String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;
		strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;
		return strDay + " " + strHour + ":" + strMinute + ":" + strSecond + " " + strMilliSecond;
	}
}
